package com.ruleengine.parser.impl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.log4j.Logger;
import org.dom4j.Element;

import com.ruleengine.parser.ITaskContants;
import com.ruleengine.parser.ITaskParser;
import com.ruleengine.parser.exception.RuleEngineParserException;
import com.ruleengine.task.ITask;
import com.ruleengine.task.config.TaskConfigManager;
import com.ruleengine.task.handler.IExceptionHandler;
import com.ruleengine.task.handler.IHandler;
import com.ruleengine.task.handler.impl.DefaultExceptionHandler;
import com.ruleengine.task.handler.impl.DefaultHandler;

/**
 *解析器模板类.
 *针对具体task的解析器需要继承该类，实现其中的
 *抽象方法.
 * @author wuxiao
 * Created on Apr 15, 2012
 */
public  class BaseTaskParser<E extends ITask> implements ITaskParser<E> {
    private static Logger logger = Logger.getLogger(BaseTaskParser.class);
    /* (non-Javadoc)
     * @see com.wx.workflow.parser.ITaskParser#parse(org.dom4j.Element)
     */
    public  E parse(Element ele) throws RuleEngineParserException {
        // TODO Auto-generated method stub
        logger.debug("parse node <"+ele.getName() + "> ");
        E task = TaskConfigManager.getInstance().createTask(ele.getName());
        
        /*
         * 前处理*/
        task = preParseTask(ele, task);
        
        /*
         * 解析子节点部分*/
        task = parseTask(ele, task);

        /*
         * 后处理*/
        task = preParseTask(ele, task);
        
        /*
         * 解析异常配置*/
        Element insEle = insEle = ele.element(ITaskContants.ELE_TAG_EXCEPTIONHANDLERS);
        if(insEle!=null){
            //配置了异常处理器
            IExceptionHandler exceptions = praseExceptions(insEle);
            task.setExceptionHandler(exceptions);
        }
        
        return task; 
    }

    /**
     * 解析各个task的子任务.
     * 该方法只需要解析子任务（subtask）部分，不需要解析
     * 前（后）拦截器（interceptors）、异常处理模块（exceptionhandlers）块.
     * @param ele task任务的配置节点
     * @param task 解析结果
     * @return
     * @throws WorkflowParseException
     */
    public E parseTask(Element ele,E task) throws RuleEngineParserException{
        return task;
    }

    /**
     * 前置解析.
     * 该方法主要是在调用parseTask方法之前，做些预处理.
     * @param ele task任务的配置节点
     * @param task 解析结果
     * @return
     * @throws WorkflowParseException
     */
    public E preParseTask(Element ele,E task) throws RuleEngineParserException{
        return task;
    }
    

    /**
     * 后置解析.
     * 该方法主要是在调用parseTask方法之后，做些预处理.
     * @param ele task任务的配置节点
     * @param task 解析结果
     * @return
     * @throws WorkflowParseException
     */
    public E postParseTask(Element ele,E task) throws RuleEngineParserException{
        return task;
    }
    
    private IExceptionHandler praseExceptions(Element exsEle) throws RuleEngineParserException{
        IExceptionHandler ins = new DefaultExceptionHandler();
        
        //解析handler块定义
        Iterator<Element> it = exsEle.elementIterator(ITaskContants.ELE_TAG_HANDLER);
        while(it.hasNext()){
            //解析每个异常处理（handler）
            Element in = it.next();
            IHandler dti = new DefaultHandler();
            
            //解析捕捉的异常（cause）
            String causes = in.attributeValue(ITaskContants.ELE_TAG_CAUSE);
            List<String> cs = new ArrayList<String>();
            for(String c : causes.split(",")){
                if("".equals(c.trim())){
                    continue;
                }
                cs.add(c);
            }
            dti.setCauses(cs);

            //解析cause的子流程
            List<ITask> handlers = new ArrayList<ITask>();
            List children = in.elements();
            for(int i=0; i < children.size(); i++){
                Element child = (Element)children.get(i);
                if(TaskConfigManager.getInstance().isWorkflowElement(child.getName())){
                    //找到第一个工作流节点组
                    ITaskParser parser = TaskConfigManager.getInstance().getTaskParser(child.getName());
                    ITask handler = parser.parse(child);
                    handlers.add(handler);
                    break;
                }
            }
            dti.setHandlerTask(handlers);
            ins.addHandler(dti);
        }
        
        //解析finally块
        it = exsEle.elementIterator(ITaskContants.ELE_TAG_FINALLY);
        while(it.hasNext()){
            Element in = it.next();
            //解析第一个工作流节点
            List children = in.elements();
            for(int i=0; i < children.size(); i++){
                Element child = (Element)children.get(i);
                if(TaskConfigManager.getInstance().isWorkflowElement(child.getName())){
                    //找到第一个工作流节点组
                    ITaskParser parser = TaskConfigManager.getInstance().getTaskParser(child.getName());
                    ITask handler = parser.parse(child);
                    ins.setFinally(handler);
                    break;
                }
            }
        }
        
        return ins;
    }
}
